﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Context.Migrations;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Dto.YS;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Newtonsoft.Json;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
using Yitter.IdGenerator;


namespace DFGK.Service
{
    public class TransferBinOrderService : BaseService, ITransferBinOrderService
    {
        private readonly ITransferBinOrderDetailRepository _transferBinOrderDetailRepository;
        private readonly IReceivingOrderDetailRepository _receivingOrderDetailRepository;
        private readonly ITransferBinOrderRepository _transferBinOrderRepository;
        private readonly IShippingLockCellRepository _lockCellRepository;
        private readonly ISupplierRepository _supplierRepository;
        private readonly IMaterialRepository _materialRepository;
        private readonly IStockRepository _stockRepository;
        private readonly HttpClientHelper _httpClientHelper;
        private readonly IReceivingBillDetailRepository _receivingBillDetailRepository;
        private readonly IInventoryLogRepository _inventoryLogRepository;
        private readonly IInterfaceLogRepository _interfaceLogRepository;
        private readonly IPutawayOrderRepository _pingOrderRepository;
        private readonly IReceivingBillRepository _receivingBillRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IInstructRepository _instructRepository;
        private readonly IPalletRepository _alletRepository;
        private readonly ICellRepository _cellRepository;
        private readonly WcsHttpClient _wcsHttpClient;
        private readonly IUnitOfWork _unitOfWork;
        public TransferBinOrderService(IMapper mapper, ITransferBinOrderDetailRepository transferBinOrderDetailRepository, ITransferBinOrderRepository transferBinOrderRepository, IUnitOfWork unitOfWork, IInventoryRepository inventoryRepository, ICellRepository cellRepository, IReceivingOrderDetailRepository receivingOrderDetailRepository, IInstructRepository instructRepository, IPutawayOrderRepository pingOrderRepository, IPalletRepository alletRepository, IInventoryLogRepository inventoryLogRepository, IShippingLockCellRepository lockCellRepository, WcsHttpClient wcsHttpClient, IInterfaceLogRepository interfaceLogRepository, IReceivingBillRepository receivingBillRepository, IReceivingBillDetailRepository receivingBillDetailRepository, ISupplierRepository supplierRepository, IMaterialRepository materialRepository, IStockRepository stockRepository, HttpClientHelper httpClientHelper) : base(mapper)
        {
            _transferBinOrderDetailRepository = transferBinOrderDetailRepository;
            _receivingOrderDetailRepository = receivingOrderDetailRepository;
            _transferBinOrderRepository = transferBinOrderRepository;
            _inventoryLogRepository = inventoryLogRepository;
            _interfaceLogRepository = interfaceLogRepository;
            _inventoryRepository = inventoryRepository;
            _pingOrderRepository = pingOrderRepository;
            _instructRepository = instructRepository;
            _lockCellRepository = lockCellRepository;
            _alletRepository = alletRepository;
            _cellRepository = cellRepository;
            _wcsHttpClient = wcsHttpClient;
            _unitOfWork = unitOfWork;
            _receivingBillRepository = receivingBillRepository;
            _receivingBillDetailRepository = receivingBillDetailRepository;
            _supplierRepository = supplierRepository;
            _materialRepository = materialRepository;
            _stockRepository = stockRepository;
            _httpClientHelper = httpClientHelper;
        }
        #region PC
        public bool AddTransferBinOrder(TransferBinOrder m, out string message)
        {
            message = "";
            m.Status = 0;

            var ilist = _inventoryRepository.GetEntityAlls().ToList();
            var clist = _cellRepository.GetEntityAlls().ToList();
            _unitOfWork.BeginTransaction();
            foreach (var item in m.OrderDetailList)
            {
                var ilists = ilist.Where(x => x.LocationId == item.FromLocationId && x.Status == 1);
                if (!ilists.Any())
                {
                    message = "找不到库存信息！";
                    return false;
                }
                foreach (var iobj in ilists)
                {
                    iobj.IsLock = true;
                    _inventoryRepository.UpdEntity(iobj);
                }
                _transferBinOrderRepository.AddEntity(m);
                _unitOfWork.SaveChangesEntity();
                item.OrderId = m.Id;
                item.OrderSn = m.OrderSn;
                item.Status = 0;
                item.MaterialId = ilists.First().MaterialId;
                item.MaterialName = ilists.First().MaterialName;
                item.FromWhId = ilists.First().WarehouseId;
                item.FromWhCode = ilists.First().WarehouseCode;
                item.FromWhName = ilists.First().WarehouseName;
                item.FromRegionId = ilists.First().AreaId;
                item.FromRegionCode = ilists.First().AreaCode;
                item.FromRegionName = ilists.First().AreaName;
                item.FromLocationName = ilists.First().LocationName;
                item.FromLocationCode = ilists.First().LocationCode;
                item.FromStockCode = ilists.First().StockCode;
                item.FromStockName = ilists.First().StockName;
                var tcobj = clist.FirstOrDefault(x => x.Id == item.ToLocationId);
                if ((tcobj == null || tcobj.IsLock == true) && (tcobj?.Code != "Cell:2_1_1_1_1"))
                {
                    message = "目标仓位异常！";
                    return false;
                }
                item.ToWhId = tcobj.WhId;
                item.ToWhCode = tcobj.WhCode;
                item.ToWhName = tcobj.WhName;
                item.ToRegionId = tcobj.AreaId;
                item.ToRegionCode = tcobj.AreaCode;
                item.ToRegionName = tcobj.AreaName;
                item.ToLocationCode = tcobj.Code;
                item.ToLocationName = tcobj.Name;
                item.ToStockCode = m.ToStockCode;
                item.ToStockName = m.ToStockName;
                item.ExpectedStackingQty = 1;
                item.Quantity = (int?)ilists.First().AvailableQty;
                item.ToLogicalPartCode = ilists.First().PalletBarcode;
                _transferBinOrderDetailRepository.AddEntity(item);
                tcobj.IsLock = true;
                tcobj.FullStatus = 1;
                tcobj.BusinessType = 1;
                tcobj.ModifyDate = DateTime.Now;
                _cellRepository.UpdEntity(tcobj);
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                _unitOfWork.CommitChanges();
                var first = m.OrderDetailList.FirstOrDefault();
                var areacode = first.FromRegionCode;
                //if (areacode.Contains("P"))
                //{
                //    StaticFinishTransferBinOrder(putcode, out message);
                //}
                return true;
            }
            _unitOfWork.RollbackChanges();
            return true;
        }

        public bool DelTransferBinOrder(long id, out string message)
        {
            message = string.Empty;
            var tobj = _transferBinOrderRepository.QueryEntityById(id);
            if (tobj != null)
            {
                if (tobj.Status == 3 || tobj.Status == 4)
                {
                    message = "作业中和已完成的数据无法删除！";
                    return false;
                }
                _transferBinOrderRepository.DelEntity(tobj);
                var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == tobj.Id);
                if (tdobj == null)
                {
                    message = "明细信息有误！";
                    return false;
                }
                _transferBinOrderDetailRepository.DelEntity(tdobj);
                if (tdobj.ToLocationId == null)
                {
                    message = "目标仓位信息有误！";
                    return false;
                }
                var cobj = _cellRepository.QueryEntityById((long)tdobj.ToLocationId);
                if (cobj != null && cobj.IsLock == false)
                {
                    message = "仓位状态有误！";
                    return false;
                }
                if (cobj != null)
                {
                    cobj.FullStatus = 0;
                    cobj.IsLock = false;
                    cobj.BusinessType = 0;
                    cobj.ModifyDate = DateTime.Now;
                    _cellRepository.UpdEntity(cobj);
                }
                var iobj = _inventoryRepository.QueryEntityWhere(x => x.LocationId == tdobj.FromLocationId);
                if (iobj != null)
                {
                    iobj.IsLock = false;
                    _inventoryRepository.UpdEntity(iobj);
                }
                return _unitOfWork.SaveChangesEntity();
            }
            message = "找不到移库单数据！";
            return false;
        }

        public TransferBinOrder? GetTransferBinOrderById(long id)
        {
            var tobj = _transferBinOrderRepository.QueryEntityById(id);
            if (tobj != null)
            {
                var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == tobj.Id);
                if (tdobj != null)
                    tobj.OrderDetailList.Add(tdobj);
                return tobj;
            }
            return null;
        }

        public List<TransferBinOrder> GetTransferBinOrderList(string? key, int status, int pageIndex, int pageSize, out int totalCount)
        {
            var tlist = _transferBinOrderRepository.GetEntityAlls();
            if (!string.IsNullOrEmpty(key))
            {
                tlist = tlist.Where(c => c.OrderSn.Contains(key));
            }
            if (status < 8)
            {
                tlist = tlist.Where(c => c.Status == status);
            }
            var list = _transferBinOrderRepository.GetEntityAlls(tlist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return list.ToList();
        }

        public bool UpdTransferBinOrder(TransferBinOrder m, out string message)
        {
            message = "";
            if (m.Status == 3 || m.Status == 4)
            {
                message = "作业中和已完成的单据不可修改！";
                return false;
            }
            var ilist = _inventoryRepository.GetEntityAlls();
            var clist = _cellRepository.GetEntityAlls();
            _unitOfWork.BeginTransaction();
            var tdobj = _transferBinOrderDetailRepository.QueryEntityWhere(x => x.OrderId == m.Id);
            if (tdobj != null)
                _transferBinOrderDetailRepository.DelEntity(tdobj);
            foreach (var item in m.OrderDetailList)
            {
                var iobj = ilist.FirstOrDefault(x => x.LocationId == item.FromLocationId && x.Status == 1);
                if (iobj == null)
                {
                    message = "找不到库存信息！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                _transferBinOrderRepository.UpdEntity(m);
                _unitOfWork.SaveChangesEntity();
                item.OrderId = m.Id;
                item.OrderSn = m.OrderSn;
                item.Status = 0;
                item.MaterialId = iobj.MaterialId;
                item.MaterialName = iobj.MaterialName;
                item.FromWhId = iobj.WarehouseId;
                item.FromWhCode = iobj.WarehouseCode;
                item.FromWhName = iobj.WarehouseName;
                item.FromRegionId = iobj.AreaId;
                item.FromRegionCode = iobj.AreaCode;
                item.FromRegionName = iobj.AreaName;
                item.FromLocationName = iobj.LocationName;
                item.FromLocationCode = iobj.LocationCode;
                var tcobj = clist.FirstOrDefault(x => x.Id == item.ToLocationId);
                if (tcobj == null || tcobj.IsLock == true)
                {
                    message = "目标仓位异常！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                item.ToWhId = tcobj.WhId;
                item.ToWhCode = tcobj.WhCode;
                item.ToWhName = tcobj.WhName;
                item.ToRegionId = tcobj.AreaId;
                item.ToRegionCode = tcobj.AreaCode;
                item.ToRegionName = tcobj.AreaName;
                item.ToLocationCode = tcobj.Code;
                item.ToLocationName = tcobj.Name;
                item.ExpectedStackingQty = 1;
                item.Quantity = (int?)iobj.AvailableQty;
                item.ToLogicalPartCode = iobj.PalletBarcode;
                _transferBinOrderDetailRepository.AddEntity(item);
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                _unitOfWork.CommitChanges();
                return true;
            }
            _unitOfWork.RollbackChanges();
            return true;
        }
        #endregion

        #region PDA
        public bool StartTransferBinOrder(TransferBinOrderDTO m, out string message)
        {
            message = string.Empty;
            bool result = false;
            string putcode = "";
            _unitOfWork.BeginTransaction();
            try
            {
                var tranbdeobj = _transferBinOrderDetailRepository.QueryEntityById(m.Id);
                if (tranbdeobj == null)
                {
                    message = "找不到移库单明细！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.OrderId == null)
                {
                    message = "移库单id有误！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.Status == 3)
                {
                    message = "该任务正在作业中！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (tranbdeobj.Status == 4)
                {
                    message = "该任务已完成！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                var tranbobj = _transferBinOrderRepository.QueryEntityById((long)tranbdeobj.OrderId);
                if (tranbobj == null)
                {
                    message = "找不到移库单";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                tranbobj.Status = 3;
                tranbdeobj.Status = 3;
                #region 原始仓位
                var fromCell = _cellRepository.QueryIsEntityWhere(it => it.Code == m.LocationCode);
                if (fromCell == null)
                {
                    message = "原始仓位不存在";
                    return false;
                }
                if (fromCell.Status != 1 || fromCell.IsLock == false)
                {
                    message = "原始仓位库存，无法执行任务";
                    return false;
                }
                else
                {
                    fromCell.FullStatus = 0;
                    fromCell.IsLock = false;
                    fromCell.BusinessType = 0;
                    fromCell.ModifyUserId = m.NowUserId;
                    fromCell.ModifyUserName = m.NowUserName;
                    _cellRepository.UpdEntity(fromCell);
                }
                #endregion
                #region 如果浅深位有货物产生移库操作
                if (fromCell.AreaCode.Contains('L'))
                {

                    //排
                   // string rows = fromCell.Code.Substring(7, 1);
                    string[] parts12 = fromCell.Code.Split('_');
                    string rows = parts12[1];
                    if (string.IsNullOrEmpty(rows))
                    {
                        message = "获取仓位排失败！";
                        return false;
                    }
                    if (rows == "1")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_2_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "5")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_4_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "6")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_7_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "10")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_9_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "11")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_12_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "15")
                    {
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_14_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                }
                #endregion
                #region 目标仓位
                var toCell = _cellRepository.QueryIsEntityWhere(it => it.Code == m.TargetLocationCode);
                if ((toCell == null || toCell.Status != 1) && (toCell?.Code != "Cell:2_1_1_1_1"))
                {
                    message = "目标仓位不存在";
                    return false;
                }
                #endregion
                #region 如果浅深位有货物产生移库操作
                if (toCell.AreaCode.Contains('L'))
                {
                    //排
                    //string rows = toCell.Code.Substring(7, 1);
                    string[] parts12 = fromCell.Code.Split('_');
                    string rows = parts12[1];
                    if (string.IsNullOrEmpty(rows))
                    {
                        message = "获取仓位排失败！";
                        return false;
                    }
                    if (rows == "1")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_2_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "5")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_4_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "6")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_7_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "10")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_9_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "11")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_12_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                    else if (rows == "15")
                    {
                        string[] parts = toCell.Code.Substring(5).Split(separator: '_');
                        int rou = Convert.ToInt32(parts[0]); // 巷道是第一个数字
                        int row = Convert.ToInt32(parts[1]);    // 排是第二个数字
                        int col = Convert.ToInt32(parts[2]);    // 列是第三个数字
                        int lev = Convert.ToInt32(parts[3]);  // 层是第
                        string modifiedcellcode = $"Cell:{rou}_14_{col}_{lev}_1";
                        var inventorycell = _inventoryRepository.QueryEntityWhere(x => x.LocationCode == modifiedcellcode);
                        if (inventorycell != null)
                        {
                            message = $"浅货位 {modifiedcellcode} 已有物资，请先移走在进行操作！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                    }
                }
                #endregion
                #region 修改库存状态
                var inventorylist = _inventoryRepository.GetEntityWhereAll(it => it.LocationId == fromCell.Id).ToList();
                if (!inventorylist.Any())
                {
                    message = "库存不存在";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                foreach (var inventory in inventorylist)
                {
                    inventory.LocationId = toCell.Id;
                    inventory.LocationName = toCell.Name;
                    inventory.LocationCode = toCell.Code;
                    inventory.LocationDepth = toCell.DepthIndex;
                    inventory.LocationLineNo = toCell.LineNo;
                    inventory.LocationLayerNo = toCell.LayerNo;
                    inventory.LocationColumnNo = toCell.ColumnNo;
                    inventory.Status = 2;
                    inventory.LocationHeightType = toCell.HeightType;
                    inventory.RoutewayId = toCell.RoutewayId;
                    _inventoryRepository.UpdEntity(inventory);
                    #region 关联的入库单做处理
                    if (inventory.RelatedOrderDetailId == null)
                    {
                        message = "关联入库单id有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    var revingobj = _receivingOrderDetailRepository.QueryEntityById((long)inventory.RelatedOrderDetailId);
                    if (revingobj == null)
                    {
                        message = "入库单明细不存在或已被删除";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    else
                    {
                        revingobj.LocationId = toCell.Id;
                        revingobj.LocationCode = toCell.Code;
                        revingobj.LocationName = toCell.Name;
                        revingobj.ModifyDate = DateTime.Now;
                        _receivingOrderDetailRepository.UpdEntity(revingobj);
                    }
                    #region 指令管理
                    Instruct instruct = null;
                    instruct = new Instruct
                    {
                        WarehouseCode = toCell.WhCode,
                        Status = 2,
                        FromLocation = fromCell.Code,
                        ToLocation = toCell.Code,
                        StackingStorageId = 0,
                        WorkDeviceType = 1,
                        InstructType = 3,
                        Action = 0,
                        RelatedOrderId = tranbobj.Id,
                        RelatedOrderDetailId = m.Id,
                        DeviceCode = "",
                        ExpectedToLocation = toCell.Code,
                        InstructIndex = 1,
                        PalletBarcode = inventory.PalletBarcode,
                        ScanedBarcode = inventory.PalletBarcode,
                        Priority = 9999,
                        Qty = inventory.AvailableQty == null ? 0 : (decimal)inventory.AvailableQty,
                        FinishedQty = 0,
                        CreateDate = DateTime.Now,
                        BusinessType = (int)EmBusinessType.Move,
                        BillType = (int)revingobj.BillType.GetValueOrDefault(),
                    };
                    _instructRepository.AddEntity(instruct);
                    #endregion
                    #region 上架单
                    string str = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                    string traawayCode = "TRA" + str;
                    PutawayOrder putawayOrder = new PutawayOrder();
                    putawayOrder.Id = YitIdHelper.NextId();
                    putawayOrder.Code = traawayCode;
                    putawayOrder.RelatedOrderDetailId = inventory.RelatedOrderDetailId;
                    putawayOrder.StackingStorageId = 0;
                    putawayOrder.PalletBarcode = inventory.PalletBarcode;
                    putawayOrder.LocationCode = toCell.Code;
                    putawayOrder.LocationDepth = toCell.DepthIndex == 0 ? null : toCell.DepthIndex;
                    putawayOrder.Status = 4;
                    putawayOrder.Qty = inventory.AvailableQty;
                    putawayOrder.CreateDate = DateTime.Now;
                    putawayOrder.MaterialId = inventory.MaterialId;
                    putawayOrder.MaterialCode = inventory.MaterialCode;
                    putawayOrder.MaterialName = inventory.MaterialName;
                    putawayOrder.MaterialKeyId = inventory.MaterialKeyId;
                    putawayOrder.BatchNo = inventory.BatchNo;
                    putawayOrder.CreateUserId = 0;
                    putawayOrder.CreateUserName = "系统";
                    putawayOrder.SourceType = 3;
                    putawayOrder.Roadway = toCell.RoutewayId.ToString();
                    _pingOrderRepository.AddEntity(putawayOrder);
                    putcode = putawayOrder.Code;
                    if (_unitOfWork.SaveChangesEntity() == false)
                    {
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    #endregion
                }
                #endregion
                var pallobj = _alletRepository.QueryIsEntityWhere(x => x.PalletBarcode == tranbdeobj.ToLogicalPartCode);

                if (pallobj != null)
                {
                    pallobj.LocationName = toCell.Name;
                    pallobj.LocationCode = toCell.Code;
                    _alletRepository.UpdEntity(pallobj);
                    result = _unitOfWork.SaveChangesEntity();
                }


                if (inventorylist.First().AreaCode.Contains('P'))
                {
                    result = StaticFinishTransferBinOrder(putcode, out message);


                }


                #endregion
                //提交事务
                if (result)
                {
                    #region 堆垛机                
                    if (Config.IsDev == false)
                    {
                        var putobj = _pingOrderRepository.QueryEntityWhere(x => x.PalletBarcode == tranbdeobj.ToLogicalPartCode && x.Status == 4 && x.SourceType == 3);
                        if (putobj == null)
                        {
                            message = "找不到上架单信息！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        string[] parts = fromCell.Code.Substring(5).Split(separator: '_');
                        string[] toparts = putobj.LocationCode.Substring(5).Split(separator: '_');
                        //移库
                        WcsTranTaskDto wcsTaskDto = new WcsTranTaskDto
                        {
                            TaskCode = putobj.Code,
                            FromTunnel = Convert.ToInt32(parts[0]),
                            FromRow = Convert.ToInt32(parts[1]),
                            FromBay = Convert.ToInt32(parts[2]),
                            FromLevel = Convert.ToInt32(parts[3]),
                            ToTunnel = Convert.ToInt32(toparts[0]),
                            ToRow = Convert.ToInt32(toparts[1]),
                            ToBay = Convert.ToInt32(toparts[2]),
                            ToLevel = Convert.ToInt32(toparts[3]),
                            PalletCode = putobj.PalletBarcode,
                        };
                        var wcsresult = _wcsHttpClient.TranTaskApi(wcsTaskDto);
                        if (wcsresult.Code != EmApiResCode.Success)
                        {
                            message = wcsresult.ReturnInfo;
                            _unitOfWork.RollbackChanges();
                            InterfaceLog interfaceLog = new InterfaceLog();
                            interfaceLog.Name = "SendMoveTask";
                            interfaceLog.Url = "wcs/ExternalApi/SendMoveTask";
                            interfaceLog.CallWay = 2;
                            interfaceLog.CallWayStr = "POST";
                            interfaceLog.InParam = JsonConvert.SerializeObject(m);
                            interfaceLog.ExecDate = DateTime.Now;
                            interfaceLog.FinishedDate = DateTime.Now;
                            interfaceLog.Status = 3;
                            interfaceLog.OutParam = $"移库失败！托盘号{tranbdeobj.ToLogicalPartCode} 仓位{fromCell.Code}";
                            interfaceLog.ErrorMsg = message;
                            _interfaceLogRepository.AddEntity(interfaceLog);
                            _unitOfWork.SaveChangesEntity();
                            return false;
                        }
                        else
                        {
                            InterfaceLog interfaceLog = new InterfaceLog();
                            interfaceLog.Name = "SendMoveTask";
                            interfaceLog.Url = "wcs/ExternalApi/SendMoveTask";
                            interfaceLog.CallWay = 2;
                            interfaceLog.CallWayStr = "POST";
                            interfaceLog.InParam = JsonConvert.SerializeObject(m);
                            interfaceLog.OutParam = wcsresult.ReturnInfo + $"(移库)托盘{tranbdeobj.ToLogicalPartCode}原仓位{fromCell.Code}已被移动至{toCell.Code}";
                            interfaceLog.ExecDate = DateTime.Now;
                            interfaceLog.FinishedDate = DateTime.Now;
                            interfaceLog.Status = 1;
                            _interfaceLogRepository.AddEntity(interfaceLog);
                            _unitOfWork.SaveChangesEntity();
                        }
                    }
                    #endregion
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception ex)
            {
                //事务回滚
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        private bool StaticFinishTransferBinOrder(string putcode, out string message)
        {
            //1
            long TransferBinOrderDeatilId = 0;
            bool IsNullPallet = false;
            message = string.Empty;
            var putobj = _pingOrderRepository.QueryEntityWhere(x => x.Code == putcode && x.SourceType == 3 && x.Status == 4);
            var robj = _receivingOrderDetailRepository.GetEntityAlls();
            if (putobj == null)
            {
                message = "找不到上架单！";
                _unitOfWork.RollbackChanges();
                return false;
            }
            string? pallbarcode = putobj.PalletBarcode;

            //if (string.IsNullOrEmpty(pallbarcode))
            //{
            //    message = "托盘信息有误！";
            //    _unitOfWork.RollbackChanges();
            //    return false;
            //}
            var instructlist = _instructRepository.GetEntityWhereAll(x => x.PalletBarcode == pallbarcode && x.Status == 2 && x.InstructType == 3).ToList();
            if (!instructlist.Any())
            {
                message = "未查询到指令！";
                _unitOfWork.RollbackChanges();
                return false;
            }
            var tlist = _transferBinOrderRepository.GetEntityAll();
            var tdlist = _transferBinOrderDetailRepository.GetEntityAll();
            foreach (var instruct in instructlist)
            {
                instruct.Status = 4;
                instruct.EndTime = DateTime.Now;
                _instructRepository.UpdEntity(instruct);
                var fromcell = _cellRepository.QueryEntityWhere(x => x.Code == instruct.FromLocation && x.FullStatus == 1);
                if (fromcell != null)
                {
                    fromcell.FullStatus = 0;
                    fromcell.IsLock = false;
                    fromcell.BusinessType = 0;
                    _cellRepository.UpdEntity(fromcell);
                }
                var invobj = _inventoryRepository.QueryEntityWhere(x => x.PalletBarcode == instruct.PalletBarcode && x.Status == 2 && x.IsLock == true);
                if (invobj.PalletBarcode == "0")
                {
                    IsNullPallet = false;
                }
                else
                {
                    IsNullPallet = true;
                }
                if (invobj == null)
                {
                    message = "库存中找不到该托盘！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                if (invobj.Remark != "系统移库")
                {
                    invobj.Status = 1;
                    invobj.IsLock = false;
                }
                else
                    invobj.Status = 1;
                _inventoryRepository.UpdEntity(invobj);
                var tobj = tlist.FirstOrDefault(x => x.Id == instruct.RelatedOrderId);
                if (tobj != null)
                {
                    tobj.Status = 4;
                    _transferBinOrderRepository.UpdEntity(tobj);
                }
                var tdobj = tdlist.FirstOrDefault(x => x.Id == instruct.RelatedOrderDetailId);
                if (tdobj != null)
                {
                    TransferBinOrderDeatilId = tdobj.Id;
                    tdobj.Status = 4;

                    _transferBinOrderDetailRepository.UpdEntity(tdobj);
                }
                var slocklist2 = _lockCellRepository.GetEntityWhereAll(x => x.CellCode == instruct.ToLocation && x.Status != 4).ToList();
                foreach (var item3 in slocklist2)
                {
                    item3.Status = 0;
                    _lockCellRepository.UpdEntity(item3);
                }
                var treivingobj = robj.FirstOrDefault(x => x.Id == invobj.RelatedOrderDetailId);
                if (treivingobj == null)
                {
                    message = "找不到入库单或已被删除！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }
                var inventoryLog = new InventoryLog
                {
                    Id = YitIdHelper.NextId(),
                    SourceType = 2,
                    SourceSn = treivingobj.OrderSn,
                    WarehouseId = invobj.WarehouseId,
                    WarehouseName = invobj.WarehouseName,
                    AreaName = invobj.AreaName,
                    AreaId = invobj.AreaId,
                    LocationCode = invobj.LocationCode,
                    PalletBarcode = instruct.PalletBarcode,
                    MaterialId = invobj.MaterialId,
                    MaterialCode = invobj.MaterialCode,
                    MaterialName = invobj.MaterialName,
                    BatchNo = invobj.BatchNo,
                    StartQty = invobj.AvailableQty,
                    ChangeQty = 0,
                    EndQty = invobj.AvailableQty,
                    BaseUnitId = 0,
                    BaseUnitName = invobj.UnitName,
                    Remark = "原：" + instruct.FromLocation,
                    CreateDate = DateTime.Now
                };
                _inventoryLogRepository.AddEntity(inventoryLog);
                if (!_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.RollbackChanges();
                    return false;
                }
            }
            var putlist = _pingOrderRepository.GetEntityWhereAll(x => x.SourceType == 3 && x.Status == 4 && x.PalletBarcode == pallbarcode);
            foreach (var item in putlist)
            {
                item.Status = 5;
                item.Fifodate = DateTime.Now;
                _pingOrderRepository.UpdEntity(item);
            }
            if (_unitOfWork.SaveChangesEntity())
            {
                if (!Config.IsDevErp)
                {
                    if (IsNullPallet)
                    {
                        var putobj1 = _pingOrderRepository.QueryEntityWhere(x => x.Code == putcode && x.SourceType == 3 && x.Status == 5);
                        if (putobj1 == null)
                        {
                            message = "未找到对应的Ping订单";
                            return false;
                        }

                        var receivingOrderDetail = _receivingOrderDetailRepository.QueryEntityWhere(d => d.Id == putobj1.RelatedOrderDetailId);
                        if (receivingOrderDetail == null)
                        {
                            message = "未找到关联的收货订单明细";
                            return false;
                        }

                        if (TransferBinOrderDeatilId <= 0)
                        {
                            message = "回传失败找不到对应的单据";
                            return false;
                        }
                        var transferBinOrderDeatil = _transferBinOrderDetailRepository.QueryEntityWhere(d => d.Id == TransferBinOrderDeatilId);
                        if (transferBinOrderDeatil == null)
                        {
                            message = "转移仓单明细不存在";
                            return false;
                        }

                        var isvmi = transferBinOrderDeatil.FromStockName?.Contains("VMI") ?? false ? "Y" : "N";

                        var receivingBill = _receivingBillRepository.QueryEntityWhere(d => d.Id == receivingOrderDetail.ReceivingBillId);
                        if (receivingBill == null)
                        {
                            message = "收货单据不存在";
                            return false;
                        }
                        var supplierCode = string.Empty;

                        if (!string.IsNullOrEmpty(receivingBill.SupplierName))
                        {
                            var supplier = _supplierRepository.QueryEntityWhere(d => d.Id == receivingBill.SupplierId);
                            if (isvmi == "Y")
                            {
                                supplierCode = supplier.Code;
                            }
                            supplierCode = "";
                        }

                        var modelSpec = string.Empty;
                        var UnitName = string.Empty;
                        if (!string.IsNullOrEmpty(putobj1.MaterialCode))
                        {
                            var material = _materialRepository.QueryEntityWhere(d => d.Code == putobj1.MaterialCode);
                            modelSpec = material.ModelSpec;
                            UnitName = material.UnitName;
                        }

                        var stockCode = string.Empty;
                        var stockPlace = string.Empty;
                        if (!string.IsNullOrEmpty(receivingBill.StockCode))
                        {
                            var stock = _stockRepository.QueryEntityWhere(d => d.StockCode == receivingBill.StockCode);
                            stockCode = stock.StockCode;
                            stockPlace = stock.SPGroupCode;
                        }
                        if (!string.IsNullOrEmpty(putobj1.LocationCode))
                        {
                            var cell = _cellRepository.QueryEntityWhere(d => d.Code == putobj1.LocationCode);
                            if (cell.AreaCode.Contains("P"))
                            {
                                BackTransferStockDto backTransferStockDto = new BackTransferStockDto
                                {
                                    Entry = new List<BackTransferStockDetailDto>()
                                };
                                backTransferStockDto.BillId = receivingOrderDetail.Id;
                                backTransferStockDto.BillDate = receivingBill.BeginDate.HasValue
                                ? receivingBill.BeginDate.Value.ToString("yyyy-MM-dd HH:mm:ss")
                                : string.Empty;
                                BackTransferStockDetailDto backTransferStockDetail = new BackTransferStockDetailDto
                                {
                                    Number = receivingOrderDetail.MaterialCode,
                                    Name = receivingOrderDetail.MaterialName,
                                    Model = modelSpec,
                                    Unit = UnitName,
                                    Qty = (decimal)putobj1.Qty,
                                    BatchNo = receivingOrderDetail.BatchNo,
                                    OutStockNumber = transferBinOrderDeatil.FromStockCode,
                                    OutStockPlace = transferBinOrderDeatil.FromStockName,
                                    IsVMI = isvmi,
                                    SupplierNumber = supplierCode,
                                    InStockNumber = transferBinOrderDeatil.ToStockCode,
                                    InStockPlace = transferBinOrderDeatil.ToStockName
                                };
                                backTransferStockDto.Entry.Add(backTransferStockDetail);
                                
                               
                                string targeUrl = "http://59.110.231.187:9883/api/1";
                                try
                                {
                                    var jsonData = JsonConvert.SerializeObject(backTransferStockDto);
                                    var resultt =  _httpClientHelper.PostAsync<WcsTaskResultDto>(
                                        targeUrl, 
                                        jsonData,
                                        "application/json"
                                    ).Result;

                                    if (resultt?.Code != EmApiResCode.Success)
                                    {
                                        message = resultt?.Msg ?? "ERP接口调用移库失败";
                                        return false;
                                    }
                                    resultt.Data = backTransferStockDto.BillId;

                                    return true;
                                }
                                catch (Exception e)
                                {
                                    message = e.Message;
                                    return false;
                                }

                            }
                        }
                    }
                   
                }
                return true;
            }
            return false;
        }

        public bool FinishTransferBinOrder(string putcode, out string message)
        {
            _unitOfWork.BeginTransaction();
            try
            {
                bool result = StaticFinishTransferBinOrder(putcode, out message);
                if (result)
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
        #endregion
    }

}
